import datetime
import os
import traceback
from time import *

from DataProcess.DataProcesser import DataProcesser
from DataProcess.BaiDuNLP import *
from General.Mapper import *
import logging


class DataProcessWrapper:
    tagMapper = TagMapper()
    rawDataMapper = RawDataMapper()
    topicMapper = TopicMapper()
    dataProcess = DataProcesser()
    wordMapper = WordMapper()
    wordCountMapper = WordCountMapper()
    topicCountMapper = TopicCountMapper()
    tagCountMapper = TagCountMapper()
    topicToWordMapper = TopicToWordMapper()
    wordParseNlp = NLP()

    # 设置logger
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    rq = datetime.datetime.now().strftime('%Y%m%d%H%M')
    log_path = os.path.dirname(os.getcwd()) + '/Logs/DataParseLogs/'
    log_name = log_path + rq + '.log'
    logfile = log_name
    fh = logging.FileHandler(logfile, mode='w')
    fh.setLevel(logging.DEBUG)
    formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")
    fh.setFormatter(formatter)
    logger.addHandler(fh)

    def processADayData(self, date: datetime.date):
        try:
            self.logger.info("开始解析:" + date.strftime("%Y-%m-%d") + "日期的数据")

            # 预设处理时间
            processTime: datetime = datetime.datetime(date.year, date.month, date.day, 22, 00, 0)
            # 处理当天数据的时间的起止时间
            starTime: datetime = datetime.datetime(processTime.year, processTime.month, processTime.day, 0, 0, 0)
            endTime: datetime = datetime.datetime(processTime.year, processTime.month, processTime.day, 23, 59, 59)

            unparseTopicList: list = self.topicMapper.getUnparseTopic(starTime, endTime)  # 获取该日未处理话题
            unparseRawDataList: list = self.rawDataMapper.getUnparseRawData(starTime, endTime)  # 获取该日未处理原始数据

            #
            # 开始统计Tag
            self.logger.info("开始统计" + date.strftime("%Y-%m-%d") + "的Tag数据")
            topicList: list = self.topicMapper.allTopic()  # 所有话题列表
            tagParseMap = self.dataProcess.countTag(unparseRawDataList, topicList)  # 解析新数据
            emptyTagCountFlag = self.tagCountMapper.countRow() == 0  # 是否有过去数据flag
            # 以下获取上一次统计Tag数据
            preProcessTime = processTime - datetime.timedelta(days=1)
            preTagCountList = self.tagCountMapper.getTagCount(
                datetime.datetime(preProcessTime.year, processTime.month, preProcessTime.day, 0, 0, 0),
                datetime.datetime(preProcessTime.year, preProcessTime.month, preProcessTime.day, 23, 59, 59))
            while not emptyTagCountFlag and len(preTagCountList) == 0:
                preProcessTime = preProcessTime - datetime.timedelta(days=1)
                preTagCountList = self.tagCountMapper.getTagCount(
                    datetime.datetime(preProcessTime.year, processTime.month, preProcessTime.day, 0, 0, 0),
                    datetime.datetime(preProcessTime.year, preProcessTime.month, preProcessTime.day, 23, 59, 59))
            if emptyTagCountFlag:
                self.logger.info("Tag无老数据")
            else:
                self.logger.info("Tag老数据日期为:" + preProcessTime.strftime("%Y-%m-%d"))
            # 与老tag统计数据合并
            tagCount: dict = {}
            for item in preTagCountList:  # 老数据dict
                tagCount[item.tagId] = item.tagCount
            for item in tagParseMap:
                if item in tagCount:
                    tagCount[item] = tagCount[item] + tagParseMap[item]
                else:
                    tagCount[item] = tagParseMap[item]
            # tag解析结果写入数据库
            for item in tagCount:
                self.tagCountMapper.addTagCount(item, tagCount[item], processTime)
                sleep(0.25)
            self.logger.info("结束Tag统计")

            #
            # 开始统计Topic
            self.logger.info("开始统计" + date.strftime("%Y-%m-%d") + "的Topic数据")
            topicParseMap = self.dataProcess.countHotestTopic(unparseRawDataList)
            emptyTopicCountFlag = self.topicCountMapper.countRow() == 0
            # 以下获取上一次统计Topic的值
            preProcessTime = processTime - datetime.timedelta(days=1)
            preTopicCount = self.topicCountMapper.getTopicCount(
                datetime.datetime(preProcessTime.year, processTime.month, preProcessTime.day, 0, 0, 0),
                datetime.datetime(preProcessTime.year, preProcessTime.month, preProcessTime.day, 23, 59, 59))
            while not emptyTopicCountFlag and len(preTagCountList) == 0:
                preProcessTime = preProcessTime - datetime.timedelta(days=1)
                preTopicCount = self.topicCountMapper.getTopicCount(
                    datetime.datetime(preProcessTime.year, processTime.month, preProcessTime.day, 0, 0, 0),
                    datetime.datetime(preProcessTime.year, preProcessTime.month, preProcessTime.day, 23, 59, 59))
            if emptyTopicCountFlag:
                self.logger.info("Topic无老数据")
            else:
                self.logger.info("Topic老数据日期为:" + preProcessTime.strftime("%Y-%m-%d"))
            # 与老Topic统计数据合并
            topicCount: dict = {}
            for item in preTopicCount:  # 老数据dict
                topicCount[item.topicId] = item.topicCount
            for item in topicParseMap:
                if item in topicCount:
                    topicCount[item] = topicCount[item] + topicParseMap[item]
                else:
                    topicCount[item] = topicParseMap[item]
            # topic统计结果写入数据库
            for item in topicCount:
                self.topicCountMapper.addTopicCount(item, topicCount[item], processTime)
                sleep(0.25)
            self.logger.info("结束Topic统计")

            self.logger.info("开始拆分" + date.strftime("%Y-%m-%d") + "的Word数据")
            #
            # 准备word集合
            wordSet: dict = {}
            wordList = self.wordMapper.getAll()
            for item in wordList:
                wordSet[item.wordName] = item.id
            # 开始解析Topic名词拆分
            topicToWordMap: dict = {}
            parseResult = self.dataProcess.parseWord(unparseTopicList)
            for item in parseResult:
                for word in parseResult[item]:
                    if word in wordSet:  # 若名词已存在
                        wordId = wordSet[word]
                    else:
                        wordId = self.wordMapper.addWord(word)
                        wordSet[word] = wordId
                    # 插入到数据库
                    self.topicToWordMapper.addTopicToWord(item, wordId)
                    topicToWordMap[item] = wordId
                    sleep(0.25)
            self.logger.info("结束拆分Word数据")

            #
            # 统计word
            # 准备话题-名词映射集合
            self.logger.info("开始统计" + date.strftime("%Y-%m-%d") + "的Word数据")
            topicToWord = self.topicToWordMapper.getAll()
            # Topic-Word关系为多对多关系，此处以dict嵌套set方式做映射
            topicToWordMap: dict = {}
            for item in topicToWord:
                if item.topicId in topicToWordMap:
                    topicToWordMap[item.topicId].add(item.wordId)
                else:
                    topicToWordMap[item.topicId]: set = {item.wordId}
            # 以下获取上一次统计word的值
            self.logger.info("开始获取上一次统计word的值")
            emptyWordCountFlag = self.wordCountMapper.countRow() == 0  # 是否有过去数据flag
            preProcessTime = processTime - datetime.timedelta(days=1)
            preWordCount = self.wordCountMapper.getWordCount(
                datetime.datetime(preProcessTime.year, processTime.month, preProcessTime.day, 0, 0, 0),
                datetime.datetime(preProcessTime.year, preProcessTime.month, preProcessTime.day, 23, 59, 59))
            while not emptyWordCountFlag and len(preWordCount) == 0:
                preProcessTime = preProcessTime - datetime.timedelta(days=1)
                preWordCount = self.wordCountMapper.getWordCount(
                    datetime.datetime(preProcessTime.year, processTime.month, preProcessTime.day, 0, 0, 0),
                    datetime.datetime(preProcessTime.year, preProcessTime.month, preProcessTime.day, 23, 59, 59))
            if emptyTopicCountFlag:
                self.logger.info("Word无老数据")
            else:
                self.logger.info("Word老数据日期为:" + preProcessTime.strftime("%Y-%m-%d"))
            # 与老Word统计数据合并
            self.logger.info("开始合并Word老数据")
            wordCount: dict = {}
            for item in preWordCount:
                wordCount[item.wordId] = item.wordCount

            for item in unparseRawDataList:
                if item.topicId in topicToWordMap:
                    for wordId in topicToWordMap[item.topicId]:
                        if wordId in wordCount:
                            wordCount[wordId] = wordCount[wordId] + 1
                        else:
                            wordCount[wordId] = 1
            # word统计结果写入数据库
            self.logger.info("开始插入统计Word数据")
            for item in wordCount:
                self.wordCountMapper.addWordCount(item, wordCount[item], processTime)
                sleep(0.25)
            self.logger.info("结束统计Word数据")

            #
            # 将解析过的数据标记为已解析
            self.logger.info("开始标记为数据已解析")
            for item in unparseTopicList:
                self.topicMapper.updateProcessFlag(item.id, 1)
                sleep(0.25)
            for item in unparseRawDataList:
                self.rawDataMapper.updateRawData(item.id, 1)
                sleep(0.25)
            self.logger.info("结束数据标记")
        except Exception:  # 输出异常数据
            self.logger.error("异常：" + traceback.format_exc())


if __name__ == '__main__':
    parse = DataProcessWrapper()
    # time = datetime.datetime(2020, 12, 23, 21, 46, 47)
    time = datetime.datetime.now()
    parse.processADayData(time.date())
